/**
 * 
 */
package mycsveditor.editors;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.texteditor.ITextEditor;

/**
 * @author dongxu
 * 
 */
public class JavaCallHyperlink implements IHyperlink {

	private String fJavaCallString;
	private IRegion fRegion;
	private JavaAnalysisUtil fJavaAnalysisUtil;

	public JavaCallHyperlink(IRegion region, String javaCallString,
			JavaAnalysisUtil javaAnalysisUtil) {
		Assert.isNotNull(javaCallString);
		Assert.isNotNull(region);

		fRegion = region;
		fJavaCallString = javaCallString;
		fJavaAnalysisUtil = javaAnalysisUtil;
	}

	/**
	 * @see org.eclipse.jface.text.hyperlink.IHyperlink#getHyperlinkRegion()
	 */
	@Override
	public IRegion getHyperlinkRegion() {
		return fRegion;
	}

	/**
	 * @see org.eclipse.jface.text.hyperlink.IHyperlink#getHyperlinkText()
	 */
	@Override
	public String getHyperlinkText() {
		return fJavaCallString;
	}

	/**
	 * @see org.eclipse.jface.text.hyperlink.IHyperlink#getTypeLabel()
	 */
	@Override
	public String getTypeLabel() {
		return null;
	}

	/**
	 * @see org.eclipse.jface.text.hyperlink.IHyperlink#open()
	 */
	@Override
	public void open() {

		IMember linkDest = getLinkMember();
		if (linkDest != null) {
			openLinkInEditor(linkDest);
		} else {
			showErrorDialog("Link not found",
					"The link you are trying to open could not be found, "
							+ "the element may not exist in current project");
		}
	}

	private void openLinkInEditor(IMember linkDest) {
		IFile file = (IFile) linkDest.getResource();
		try {
			IWorkbench workbench = PlatformUI.getWorkbench();
			IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
			IWorkbenchPage p = window.getActivePage();
			IEditorPart editorPart = IDE.openEditor(p, file, true);
			ITextEditor editor = (ITextEditor) editorPart;
			ISourceRange range = linkDest.getNameRange();
			editor.selectAndReveal(range.getOffset(), range.getLength());
		} catch (Exception e) {
			showErrorDialog("Failed to open editor",
					"Failed to open Java editor");
		}
	}

	private IMember getLinkMember() {
		try {
			JavaCallNames jcn = new JavaCallNames(fJavaCallString);
			IPackageFragment pkgElement = fJavaAnalysisUtil.getPackage(jcn
					.getPkg());
			IType clazz = fJavaAnalysisUtil
					.getClazz(pkgElement, jcn.getClazz());
			if ("".equals(jcn.getMethod())) {
				return clazz;
			} else {
				return fJavaAnalysisUtil.getMethod(clazz, jcn.getMethod());
			}
		} catch (NullPointerException e) {
			return null;
		}
	}

	private void showErrorDialog(String caption, String msg) {
		MessageDialog.openError(null, caption, msg);
	}
}
